package com.hainatong.mvvmbase.http;

import com.google.gson.FieldNamingPolicy;
import com.google.gson.FieldNamingStrategy;
import com.google.gson.Gson;
import com.hainatong.mvvmbase.http.httpstool.SSLTrustAllUtil;
import com.hainatong.mvvmbase.http.interceptor.HeaderInterceptor;
import com.hainatong.mvvmbase.utils.L;
import okhttp3.*;

import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;

import java.io.IOException;
import java.lang.reflect.Field;
import java.util.concurrent.TimeUnit;

public class RetrofitHelper
{
    private static OkHttpClient mOkHttpClient;
    private volatile static RetrofitHelper retrofitHelper;

    static {
        initOkHttpClient();
    }

    /**
     * 初始化OKHttpClient,设置缓存,设置超时时间,设置打印日志,设置UA拦截器
     */
    private static void initOkHttpClient() {

        HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {
            @Override
            public void log(String message)
            {
                L.i("OkHttp", message );
            }
        });
        loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);

        //添加网络拦截器
        //NetWorkInterceptor netWorkInterceptor = new NetWorkInterceptor();
        //解析返回结果的Interceptor
        //ResponseInterceptor responseInterceptor = new ResponseInterceptor();
        //LoggingInterceptor loggingInterceptor = new LoggingInterceptor();
        HeaderInterceptor headerInterceptor = new HeaderInterceptor();

        if (mOkHttpClient == null) {
            synchronized (RetrofitHelper.class) {
                if (mOkHttpClient == null) {

                    //设置Http缓存
                    /*
                    Cache cache = new Cache(new File(RootApplication.getInstance()
                            .getCacheDir(), "HttpCache"), 1024 * 1024 * 10);
                    */
                    //ClearableCookieJar cookieJar = new PersistentCookieJar(new SetCookieCache(), new SharedPrefsCookiePersistor(App.getContext()));

                    mOkHttpClient = new OkHttpClient.Builder()
                            //暂时取消缓存
                            //.cache(cache)
                            .addInterceptor(loggingInterceptor)
                            //.addNetworkInterceptor(new CacheInterceptor())
                            .retryOnConnectionFailure(true)
                            .connectTimeout(30, TimeUnit.SECONDS)
                            .writeTimeout(20, TimeUnit.SECONDS)
                            .readTimeout(20, TimeUnit.SECONDS)
                            //解析返回结果拦截器
                            //.addInterceptor(responseInterceptor)
                            //.addInterceptor(headerInterceptor)
                            //cookie
                            //.cookieJar(cookieJar)
                            //.addInterceptor(new UserAgentInterceptor())
                            //.sslSocketFactory(sslSocketFactory, trustManager);
                            //校验SSL证书  SSLTrustAllUtil.createSSLSocketFactory()
                            .sslSocketFactory(SSLTrustAllUtil.createSSLSocketFactory())
                            //.sslSocketFactory(SSLSocketFactoryUtils.getInstance().getSslSocketFactory())
                            //校验主机名，用于域名验证
                            //.hostnameVerifier(SSLSocketFactoryUtils.getInstance().getHostnameVerifier() )
                            .build();
                }
            }
        }
    }

    /**
     * 添加UA拦截器，B站请求API需要加上UA才能正常使用
     */
    private static class UserAgentInterceptor implements Interceptor
    {
        @Override
        public Response intercept(Chain chain) throws IOException {
            Request originalRequest = chain.request();
            Request requestWithUserAgent = originalRequest.newBuilder()
                    .removeHeader("User-Agent")
                    //ua      UA标识
                    .addHeader("User-Agent", "Android")
                    .build();
            return chain.proceed(requestWithUserAgent);
        }
    }


    /**
     * 为okhttp添加缓存，这里是考虑到服务器不支持缓存时，从而让okhttp支持缓存
     */
    private static class CacheInterceptor implements Interceptor {

        @Override
        public Response intercept(Chain chain) throws IOException {

            // 有网络时 设置缓存超时时间1个小时
            int maxAge = 60 * 60;
            // 无网络时，设置超时为1天
            int maxStale = 60 * 60 * 24;
            Request request = chain.request();
            //NetworkUtil.isNetworkAvailable(MyApp.getInstance())
            if ( 1 < 2 )
            {
                //有网络时只从网络获取
                request = request.newBuilder()
                        .cacheControl(CacheControl.FORCE_NETWORK)
                        .build();
            } else {
                //无网络时只从缓存中读取
                request = request.newBuilder()
                        .cacheControl(CacheControl.FORCE_CACHE)
                        .build();
            }
            Response response = chain.proceed(request);
            //NetworkUtil.isNetworkAvailable(MyApp.getInstance())
            if ( 1 < 2)
            {
                response = response.newBuilder()
                        .removeHeader("Pragma")
                        .header("Cache-Control", "public, max-age=" + maxAge)
                        .build();
            } else {
                response = response.newBuilder()
                        .removeHeader("Pragma")
                        .header("Cache-Control", "public, only-if-cached, max-stale=" + maxStale)
                        .build();
            }
            return response;
        }
    }

    /**例子
     * 获取商品相关接口API
     * @return
     */
    //public static GoodsService getGoodsAPI()
    {
        //return createApi(GoodsService.class, Api.BASE_URL);
    }

    public static RetrofitHelper getInstance()
    {
        if (retrofitHelper == null)
        {
            synchronized (RetrofitHelper.class)
            {
                if (retrofitHelper == null)
                {
                    retrofitHelper = new RetrofitHelper();
                }
            }
        }
        return retrofitHelper;
    }


    /**
     * 根据传入的baseUrl，和api创建retrofit
     */
    private static <T> T createApi(Class<T> clazz, String baseUrl) {


        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(baseUrl)
                .client(mOkHttpClient)
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .addConverterFactory(GsonConverterFactory.create())
                .build();

        return retrofit.create(clazz);
    }


    private Gson getGson()
    {
        /*
        // 支持@Expose 注解
        GsonBuilder builder = new GsonBuilder();
        builder.excludeFieldsWithoutExposeAnnotation();
        Gson gson = builder.create();
        */

        /*
        if (gson == null)
        {
            GsonBuilder builder = new GsonBuilder();
            builder.setLenient();
            builder.setFieldNamingStrategy(new AnnotateNaming());
            builder.serializeNulls();
            gson = builder.create();
        }
        */
        return new Gson();
    }

    /**
     * gson 解析
     */
    private static class AnnotateNaming implements FieldNamingStrategy {
        @Override
        public String translateName(Field field)
        {
            ParamNames a = field.getAnnotation(ParamNames.class);
            return a != null ? a.value() : FieldNamingPolicy.IDENTITY.translateName(field);
        }
    }

    public Retrofit.Builder getBuilder(String baseUrl)
    {
        Retrofit.Builder builder = new Retrofit.Builder();
        builder.client(mOkHttpClient);
        // 设置远程地址
        builder.baseUrl(baseUrl);

        //响应 无返回值
        //builder.addConverterFactory(new NullOnEmptyConverterFactory());

        builder.addConverterFactory(GsonConverterFactory.create(getGson()));
        builder.addCallAdapterFactory(RxJava2CallAdapterFactory.create());
        return builder;
    }


    public final static String API_GANKIO = "https://gank.io/api/";
    public final static String API_DOUBAN = "Https://api.douban.com/";
    public final static String API_SITEHELPER = "https://sitehelper.hbhnt.net/";
}
